package q.yazg;

import java.util.*;
/**
 *
 * @author khalisq
 */
public class MessageThread extends Thread{    
    
    private Map<Class<? extends Message>,List<Listener>> listeners;
    private Queue<Message> queue;
    
    private boolean running;
    
    private static boolean LOG_MESSAGES = Constants.getBoolean("debug.messageLog", false);
    
    public MessageThread(){
        super("Message thread");        
        listeners = new HashMap();
        queue = new ArrayDeque<Message>(); 
        running=true;
    }
    
    /*************************************************************/
    public void run(){
        while(running){
            if(queue.isEmpty())try {
                synchronized(this){                
                    wait();
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            dispatchMessage();
        }
    }    
    /*************************************************************/
    
    public void shut(){
        running=false;        
        try {
            synchronized(this){
                this.notifyAll();
            }
            this.join();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
    
    
    public synchronized void addListener(Class<? extends Message> c, Listener l){
        if(!listeners.containsKey(c))listeners.put(c, new ArrayList());
        listeners.get(c).add(l);
    }
    
    public void sendMessage(Message msg){
        queue.add(msg);
        synchronized(this){
            this.notifyAll();
        }
    }
    
    private synchronized void dispatchMessage(){
        if(!queue.isEmpty()){
            Message msg = queue.poll();
            if(LOG_MESSAGES)System.err.println("Message dispatched: "+msg);
            for(Class<? extends Message> c:listeners.keySet()){
                if(c.isAssignableFrom(msg.getClass())){
                    for(Listener l:listeners.get(c))l.message(msg);
                }
            }
        }        
    }
}
